package com.zkzx.company.base.service;

import com.zkzx.common.company.command.CompanyCommand;
import com.zkzx.common.company.model.CompanyListVO;
import com.zkzx.common.company.model.CompanyVO;
import com.zkzx.common.company.param.CompanyFilterParam;
import com.zkzx.common.constants.SourceEnum;
import com.zkzx.common.exception.BaseException;
import com.zkzx.common.exception.ExceptionEnum;
import com.zkzx.common.global.Global;
import com.zkzx.common.vo.PageResult;
import com.zkzx.common.vo.RequestFilterParams;
import com.zkzx.common.vo.StatusVO;
import com.zkzx.company.base.client.WhAdaptorClient;
import com.zkzx.company.base.mapper.CompanyMapper;
import com.zkzx.company.base.mapper.entity.*;
import com.zkzx.company.base.service.constants.CompanyStatusEnum;
import com.zkzx.company.base.service.domian.GatherCompany;
import com.zkzx.util.json.JSONResultUtil;
import com.zkzx.util.sql.SQLUtil;
import com.zkzx.util.config.PrimaryMarkUtil;
import com.zkzx.util.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author young Email:yanghui@zkraising.com
 * @description
 * @company 北京中科智兴物联科技有限公司 @版权所有
 * @since 2021年04月29日 13时49分
 */
@Slf4j
@Service
public class CompanyService {

    @Resource
    private CompanyMapper companyMapper;

    @Autowired
    private CompanyFinanceService companyFinanceService;

    @Autowired
    private CompanyOperationService companyOperationService;

    @Autowired
    private WhAdaptorClient whAdaptorClient;


    /**
     * 分页查询企业数据
     * @param filterParam 查询条件
     * @param params 分页参数
     * @return 企业分页数据
     */
    public PageResult<CompanyListVO> find(CompanyFilterParam filterParam, RequestFilterParams params) {
        CompanyExample companyExample= new CompanyExample();

        CompanyExample.Criteria criteria = companyExample.createCriteria();

        if(!StringUtils.isEmpty(filterParam.getCid())){
            criteria.andCidLike(SQLUtil.valueBuildLike(filterParam.getCid()));
        }
        if(!StringUtils.isEmpty(filterParam.getAccountNumber())){
            criteria.andMembercodeLike(SQLUtil.valueBuildLike(filterParam.getAccountNumber()));
        }
        if(!StringUtils.isEmpty(filterParam.getName())){
            criteria.andNameLike(SQLUtil.valueBuildLike(filterParam.getName()));
        }
        if(!StringUtils.isEmpty(filterParam.getMemberName())){
            criteria.andPersonLike(SQLUtil.valueBuildLike(filterParam.getMemberName()));
        }
        if(!StringUtils.isEmpty(filterParam.getMemberMobile())){
            criteria.andMobileEqualTo(filterParam.getMemberMobile());
        }
        if(!StringUtils.isEmpty(filterParam.getStatus())){
            criteria.andStatusEqualTo(filterParam.getStatus());
        }
        if(CollectionUtils.isNotEmpty(filterParam.getStatusList())){
            criteria.andStatusIn(filterParam.getStatusList());
        }

        long totalNum = companyMapper.countByExample(companyExample);

        if (totalNum <= Global.ZERO){
            return new PageResult<>(params.getPage(),params.getPerPage(), Collections.emptyList(), Global.ZERO);
        }

        companyExample.setOrderByClause(params.getField().concat(" ").concat(params.getOrder()));
        companyExample.page(params.getPage() - Global.ONE , params.getPerPage());
        List<Company> companies = companyMapper.selectByExample(companyExample);

        List<CompanyListVO> list = companies.stream().map(company -> CompanyListVO.builder()
                .id(company.getId())
                .cid(company.getCid())
                .threeId(company.getThreeid())
                .name(company.getName())
                .code(company.getCode())
                .source(company.getSource())
                .accountNumber(company.getMembercode())
                .memberName(company.getPerson())
                .memberMobile(company.getMobile())
                .modifiedTime(DateUtil.convertDateToString(company.getLastmodifiedtime()))
                .status(StatusVO.builder()
                        .value(CompanyStatusEnum.valueOf(company.getStatus()).name())
                        .description(CompanyStatusEnum.valueOf(company.getStatus()).getDescription())
                        .build())
                .build()).collect(Collectors.toList());
        return new PageResult<>(params.getPage(),params.getPerPage(),list, (int) totalNum);
    }


    /**
     * 根据id获取企业详情信息
     * @param id 企业id
     * @return 企业详情信息
     */
    public CompanyVO getById(Integer id) {

        Company company = companyMapper.selectByPrimaryKey(id);
        if(Objects.isNull(company)){
            return null;
        }

        return CompanyVO.builder().id(company.getId()).cid(company.getCid()).threeId(company.getThreeid()).code(company.getCode())
                .name(company.getName()).type(company.getType()).accountNumber(company.getMembercode())
                .person(company.getPerson()).regAddress(company.getRegaddress())
                .regionId(company.getRegionid()).regionInfo(company.getRegioninfo()).scope(company.getScope())
                .regTime(company.getRegtime()).foundTime(company.getFoundtime()).taxAuthorities(company.getTaxauthorities())
                .regAmount(company.getRegamount()).businessPicURL(company.getBusinesspic()).licensePicURL(company.getLicensepic())
                .authorizePicURL(company.getAuthorizepic()).contractCode(company.getContractcode()).memberMobile(company.getMobile())
                .contractStartTime(company.getContractstarttime()).contractEndTime(company.getContractendtime()).contractFileURL(company.getContractfile())
                .remark(company.getRemark()).email(company.getEmail()).threeId(company.getThreeid())
                .statusVO(StatusVO.builder().value(CompanyStatusEnum.valueOf(company.getStatus()).name())
                        .context(company.getReason())
                        .description(CompanyStatusEnum.valueOf(company.getStatus()).getDescription()).build())
                .companyFinance(companyFinanceService.findVOByCompanyId(id)).source(company.getSource())
                .companyOperation(companyOperationService.findVOByCompanyId(id))
                .province(company.getProvince()).city(company.getCity()).county(company.getCounty())
                .build();
    }

    /**
     * 更新企业信息
     * @param command 入参
     * @param id 企业id
     * @param userId 运行人员id
     */
    public void update(CompanyCommand command, Integer id, int userId) {

        if(!StringUtils.isEmpty(command.getMemberMobile())) {
            CompanyExample companyExample = new CompanyExample();
            companyExample.createCriteria().andMobileEqualTo(command.getMemberMobile()).andIdNotEqualTo(id);
            List<Company> companies = companyMapper.selectByExample(companyExample);

            if (CollectionUtils.isNotEmpty(companies)) {
                throw new BaseException(ExceptionEnum.COMPANY_MOBILE_ERROR.getCode(), ExceptionEnum.COMPANY_MOBILE_ERROR.getMsg());
            }
        }

        if(!StringUtils.isEmpty(command.getAccountNumber())) {
            CompanyExample companyExample = new CompanyExample();
            companyExample.createCriteria().andMembercodeEqualTo(command.getAccountNumber()).andIdNotEqualTo(id);
            List<Company> companies = companyMapper.selectByExample(companyExample);
            if (CollectionUtils.isNotEmpty(companies)) {
                throw new BaseException(ExceptionEnum.COMPANY_MEMBER_ERROR.getCode(), ExceptionEnum.COMPANY_MEMBER_ERROR.getMsg());
            }
        }


        Company company = companyMapper.selectByPrimaryKey(id);
        GatherCompany gatherCompany = GatherCompany.builder()
                .company(company)
                .companyFinance(companyFinanceService.findByCompanyId(id))
                .companyOperation(companyOperationService.findByCompanyId(id)).build();

        command.setId(id);

        if(Objects.isNull(command.getStatusVO()) || Objects.isNull(command.getStatusVO().getValue())){
            command.setStatusVO( StatusVO.builder().value(company.getStatus()).build());
        }

        gatherCompany = CompanyStatusEnum.valueOf(command.getStatusVO().getValue())
                .buildGatherCompany(command,userId,gatherCompany);

        companyMapper.updateByPrimaryKey(gatherCompany.getCompany());
        companyFinanceService.updateOrInsert(gatherCompany.getCompanyFinance());
        companyOperationService.updateOrInsert(gatherCompany.getCompanyOperation());
    }

    /**
     * 新增企业信息
     * @param command 入参
     * @param userId 用户id
     */
    public StatusVO add(CompanyCommand command, int userId){

        CompanyExample companyExample= new CompanyExample();
        companyExample.createCriteria().andCodeEqualTo(command.getCode());
        long count = companyMapper.countByExample(companyExample);
        if(count > Global.ZERO){
            throw new BaseException(ExceptionEnum.COMPANY_CODD_ERROR.getCode(), ExceptionEnum.COMPANY_CODD_ERROR.getMsg());
        }

        Company company = new  Company();
        // 需要随机生成登录码 setaqy + 年份两位+月+日+随机四位数
        String qyMark = PrimaryMarkUtil.getQYMark();
        company.setCid(qyMark);
        company.setMembercode(qyMark);
        company.setName(command.getName());
        company.setCode(command.getCode());
        company.setSource(SourceEnum.SHARE.name());
        company.setStatus(CompanyStatusEnum.NO_EXIST.name());
        company.setCreatetime(new Date());
        company.setLastmodifiedtime(new Date());
        company.setCreateuser(userId);
        company.setLastmodifieduser(userId);
        companyMapper.insert(company);
        Optional<Company> first = companyMapper.selectByExample(companyExample).stream().findFirst();
        Integer id = 0;
        if(first.isPresent()){
            id= first.get().getId();
        }

        // 查询网货是否存在企业信息  200	不存在该数据可以直接添加 204 已有数据且审核通过 205存在状态为审核中 401 存在 状态为审核失败
        CompanyCommand whCompany = null;
        try {
            whCompany = whAdaptorClient.getCompany(id, command.getName(), command.getCode());
        } catch (Exception e) {
            // 网货异常 数据处理中 回退企业录入信息
           companyMapper.deleteByPrimaryKey(id);
            throw new BaseException(ExceptionEnum.WH_DATA_ERROR.getCode(), ExceptionEnum.WH_DATA_ERROR.getMsg());
        }
        if(Objects.isNull(whCompany)){
            return StatusVO.builder().id(id).value(CompanyStatusEnum.valueOf(company.getStatus()).name())
                    .description(CompanyStatusEnum.valueOf(company.getStatus()).getDescription()).build();
        }


        CompanyStatusEnum companyStatusEnum = CompanyStatusEnum.valueOf(whCompany.getStatusVO().getValue());

        // 更新网货的信息到数据库
        this.update(whCompany,id,userId);

        // 返回状态信息 前端根据状态信息对应展示
        return StatusVO.builder().id(id).value(companyStatusEnum.name())
                .description(companyStatusEnum.getDescription()).build();

    }

    /**
     * 提交企业数据到网货平台
     * @param id 企业id
     * @return 是否提交成功
     */
    public StatusVO submit(Integer id, Integer userId) {

        CompanyVO companyVO = this.getById(id);

        if(Objects.isNull(companyVO.getCompanyFinance()) || Objects.isNull(companyVO.getCompanyOperation())){
            throw new BaseException(ExceptionEnum.SUBMIT_COMPLETE_ERROR.getCode(),ExceptionEnum.SUBMIT_COMPLETE_ERROR.getMsg());
        }

        if(!CompanyStatusEnum.NO_EXIST.name().equals(companyVO.getStatusVO().getValue())
                && !CompanyStatusEnum.NO_REVIEW.name().equals(companyVO.getStatusVO().getValue())  ){
            throw new BaseException(ExceptionEnum.SUBMIT_ERROR.getCode(), ExceptionEnum.SUBMIT_ERROR.getMsg());
        }

        // 请求网货新增企业信息
        CompanyCommand company = whAdaptorClient.add(id, companyVO);
        log.info("请求网货新增企业信息:{}", JSONResultUtil.object2JSON(company));
        // 当合同为空的时候 才会去更新合同信息
        if(StringUtils.isEmpty(company.getContractCode())) {
            // 当返回三方信息的时候 在把合同信息传输过去 返回通过信息
            companyVO.setThreeId(Optional.ofNullable(companyVO.getThreeId()).orElse(company.getThreeId()));
            CompanyCommand contract = whAdaptorClient.getContract(id, companyVO);
            // 放入合同编号
            company.setContractCode(contract.getContractCode());
            company.setMemberMobile(companyVO.getMemberMobile());
            company.setAccountNumber(companyVO.getAccountNumber());
        }

        // 更新网货的信息到数据库
        this.update(company,id,userId);

        // 返回状态信息 前端根据状态信息对应展示
        return StatusVO.builder().id(id).value(CompanyStatusEnum.valueOf(company.getStatusVO().getValue()).name())
                .description(CompanyStatusEnum.valueOf(company.getStatusVO().getValue()).getDescription()).build();
    }

    /**
     * 更新网络对接状态
     * @param vo 企业信息
     */
    public void updateToWh(CompanyListVO vo){

        log.info("查询网货企业数据：{}",JSONResultUtil.object2JSON(vo));
        if(StringUtils.isEmpty(vo.getThreeId())){
            return;
        }
        CompanyCommand companyCommand = whAdaptorClient.getStatus(vo.getId(), vo.getThreeId());

        CompanyStatusEnum companyStatusEnum = CompanyStatusEnum.valueOf(companyCommand.getStatusVO().getValue());

        // 审核通过 更新全量数据到数据库
        if(CompanyStatusEnum.REVIEW == companyStatusEnum){
            CompanyCommand whCompany = whAdaptorClient.getCompany(vo.getId(), vo.getName(), vo.getCode());
            // 更新网货的信息到数据库
            this.update(whCompany,vo.getId(),Global.ZERO);
            return;
        }

        // 企业信息只是更新状态
        this.update(companyCommand,vo.getId(),Global.ZERO);
    }
}
